#include "wxSceneCanvas.h"
#include "wxSceneGraphicsContext.h"
#include "wxSceneView.h"
#include <osgGA/TrackballManipulator>
#include <osgviewer/CompositeViewer>
#include <osgViewer/GraphicsWindow>
// ===========================================================================
// Canvas implementation
// ===========================================================================

BEGIN_EVENT_TABLE(wxSceneCanvas, wxSceneCanvasBase)
EVT_ERASE_BACKGROUND(wxSceneCanvas::OnEraseBackground)
EVT_IDLE(wxSceneCanvas::OnIdle)
EVT_SIZE(wxSceneCanvas::OnSize)

EVT_SHOW(wxSceneCanvas::OnShow)
END_EVENT_TABLE()

wxSceneCanvas::wxSceneCanvas(osgViewer::CompositeViewer* viewer,
							 wxWindow* parent,
							 wxWindowID id,
							 const wxPoint &pos,
							 const wxSize &size,
							 const wxString &name,
							 long style,
							 int *attributes
							 ):wxSceneCanvasBase(parent,id,pos,size,name,style,attributes)
{
	pCompositeViewer = viewer;
	pGraphicContext = new wxSceneGraphicsContext(this);

	osg::State* state = new osg::State;
	state->setContextID(pGraphicContext->getGlContext());
	pGraphicContext->incrementContextIDUsageCount(pGraphicContext->getGlContext());

	pGraphicContext->setState(state);
	pGraphicContext->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	mIsRenderingActive = true;
	mIsMouseCaptured = 0;
	mUpdateOnIdle = false;
	mUpdateOnIdelOverride = false;
	SetView(new wxSceneView());
}

wxSceneCanvas::~wxSceneCanvas(void)
{
	if (pSceneView.valid())
	{
		pSceneView->setCanvas(NULL);
		pCompositeViewer->removeView(pSceneView.get());
		pSceneView = NULL;
	}
	pGraphicContext->detachFromCanvas();
}
bool wxSceneCanvas::isRenderingActive()
{
	return this->mIsRenderingActive;
}
void wxSceneCanvas::setRenderingActive(bool active)
{
  this->mIsRenderingActive=active;
}
wxSceneView* wxSceneCanvas::GetView()
{
	return pSceneView.get();
}
void wxSceneCanvas::SetView(wxSceneView* view)
{
	if (pSceneView.valid())
	{
		pCompositeViewer->removeView(pSceneView.get());
	}

	pSceneView = view;

	if (pSceneView.valid())
	{
		pSceneView->setCanvas(this);
		pCompositeViewer->addView(pSceneView.get());
		pSceneView->getCamera()->setGraphicsContext(pGraphicContext.get());

		pSceneView->setCameraManipulator(new osgGA::TrackballManipulator);
	}
}

void wxSceneCanvas::updateWhenIdle(bool update)
{
	mUpdateOnIdle = update;
	if (mUpdateOnIdle)
	{
		wxIdleEvent ev;
		::wxPostEvent(this, ev);
	}
}

void wxSceneCanvas::setUpdateWhenIdleOverride(bool status)
{
	mUpdateOnIdelOverride = status;
	if (mUpdateOnIdelOverride)
	{
		wxIdleEvent ev;
		::wxPostEvent(this, ev);
	}
}

void wxSceneCanvas::OnPaint(wxPaintEvent& event)
{	
	wxPaintDC dc(this);
	pCompositeViewer->frame();
}

void wxSceneCanvas::OnEraseBackground(wxEraseEvent& event)
{
}

void wxSceneCanvas::OnIdle(wxIdleEvent& event)
{
	if (mUpdateOnIdle || mUpdateOnIdelOverride)
	{
		Refresh();
		event.RequestMore();
	}
}

void wxSceneCanvas::OnSize(wxSizeEvent& event)
{
	if(pSceneView!=NULL){
		int width = event.GetSize().x, height = event.GetSize().y;
		pSceneView->getEventQueue()->windowResize(0, 0, width, height);
		pSceneView->getCamera()->setViewport(0, 0, width, height);
		pSceneView->getCamera()->setProjectionMatrixAsPerspective(45.0, (double)width / (double)height, 1.0, 100.0);
	}
}







void wxSceneCanvas::OnShow(wxShowEvent& event)
{
	mIsRenderingActive = event.GetShow();
	event.Skip();
}
